﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.ComponentModel;

namespace Company.RBTools_VSPackageTest.Metadata
{
    public class ExtMetadataObject
    {
        private const string XmlDeclarationString = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";
        public const string BasicExtMetadataXmlText = XmlDeclarationString + "<extedmx/>";

        public static List<string> AllNodeTypeTagNames = new List<string>() { "extedmx","imports","properties","entities","attributes"};

        public static string GetMetadataObjectTagName<T>() where T : ExtMetadataObject
        {
            return String.Empty;
        }

        public static Type GetMetadataObjectType(string tagName)
        {
            return null;
        }

        public static ExtMetadataObject SerailizeXml(XmlNode xmlNode)
        {
            Type medataObjType = null;
            switch (xmlNode.Name)
            {
                case "entity":
                    medataObjType = typeof(EntityElement);
                    break;
                case "import":
                    medataObjType = typeof(ImportElement);
                    break;
                case "property":
                    medataObjType = typeof(PropertyElement);
                    break;
                case "attribute":
                    medataObjType = typeof(AttributeElement);
                    break;
                default:
                    break;
            }
            if (medataObjType != null)
            {
                try
                {
                    XmlSerializer xmlSerializer = new XmlSerializer(medataObjType);
                    string xmlText = xmlNode.OuterXml; 
                    StringReader sReader = new StringReader(xmlText);
                    ExtMetadataObject obj = xmlSerializer.Deserialize(sReader) as ExtMetadataObject;
                    obj.TagName = xmlNode.Name;
                    return obj;
                }
                catch (Exception e)
                { }
            } 

            ExtMetadataObject metadata = new ExtMetadataObject();
            metadata.TagName = xmlNode.Name;
            return metadata; 
        }

        public static XmlNode Deserialize(ExtMetadataObject metadataObj, XmlDocument xmlDoc)
        {
            XmlNode xmlNode = xmlDoc.CreateElement(metadataObj.TagName); 
            if (metadataObj is ImportElement)
            {
                ImportElement import = metadataObj as ImportElement;
                XmlAttribute attribute = xmlDoc.CreateAttribute("namespace");
                attribute.Value = import.Namespace;
                xmlNode.Attributes.Append(attribute); 
            }
            if (metadataObj is ExtNameMetadataObject)
            {
                ExtNameMetadataObject nameEle = metadataObj as ExtNameMetadataObject;
                XmlAttribute attribute = xmlDoc.CreateAttribute("name");
                attribute.Value = nameEle.Name;
                xmlNode.Attributes.Append(attribute); 
            }

            if (metadataObj is EntityElement)
            {

            }
            if (metadataObj is PropertyElement)
            {
            }

            if (metadataObj is AttributeElement)
            {
            }
             
            return xmlNode;
        }
         
        [ReadOnly(true)]
        [XmlIgnore()]
        public string TagName
        {
            get;
            set;
        }
    }

    [XmlRoot("extedmx")]
    public class ExtEdmxRootElement : ExtMetadataObject
    {

    }

    public class ExtNameMetadataObject : ExtMetadataObject
    {
        [XmlAttribute(AttributeName = "name")]
        public string Name
        {
            get;
            set;
        }
    }
    
    [XmlRoot("import")]
    public class ImportElement : ExtMetadataObject
    {
        [XmlAttribute(AttributeName = "namespace")]
        public string Namespace
        {
            get;
            set;
        }
    }

    [XmlRoot("entity")]
    public class EntityElement : ExtNameMetadataObject
    { 
    }

    [XmlRoot("property")]
    public class PropertyElement : ExtNameMetadataObject
    {
    }

    [XmlRoot("attribute")]
    public class AttributeElement : ExtNameMetadataObject
    {
    }
}
